home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 426-450 / disk_441 / dme / src / cmd1.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  20KB  |  1,132 lines

  1.  
  2. /*
  3.  * CMD1.C   (was TEXT1.C)
  4.  *
  5.  *    (C)Copyright 1987 by Matthew Dillon,    All Rights Reserved
  6.  */
  7.  
  8. #include "defs.h"
  9.  
  10. Prototype void escapecomlinemode (void);
  11. Prototype void setpen (int);
  12. Prototype void text_cursor (int);
  13. Prototype int text_init (ED *, WIN *, struct NewWindow *);
  14. Prototype int text_switch (struct Window *);
  15. Prototype int text_sync (void);
  16. Prototype int text_load (void);
  17. Prototype int text_colno (void);
  18. Prototype int text_lineno (void);
  19. Prototype int text_lines (void);
  20. Prototype int text_cols (void);
  21. Prototype int text_imode (void);
  22. Prototype int text_tabsize (void);
  23. Prototype unsigned char *text_name (void);
  24. Prototype void text_uninit (void);
  25. Prototype void inversemode (int);
  26. Prototype void text_position (int, int);
  27. Prototype void displayblock (int);
  28. Prototype void text_redrawblock (int);
  29. Prototype void text_redisplaycurrline (void);
  30. Prototype void text_redisplay (void);
  31. Prototype void text_write (unsigned char *);
  32. Prototype void text_displayseg (int, int);
  33. Prototype void movetocursor (void);
  34. Prototype void do_up (void);
  35. Prototype void do_scrolldown (void);
  36. Prototype void do_scrollup (void);
  37. Prototype void do_down (void);
  38. Prototype void do_page (void);
  39. Prototype void do_downadd (void);
  40. Prototype void do_left (void);
  41. Prototype void do_right (void);
  42. Prototype void do_col (void);
  43. Prototype void do_tab (void);
  44. Prototype void do_backtab (void);
  45. Prototype void do_return (void);
  46. Prototype void do_bs (void);
  47. Prototype void do_recall (void);
  48. Prototype void do_esc (void);
  49. Prototype void do_del (void);
  50. Prototype void do_top (void);
  51. Prototype void do_bottom (void);
  52. Prototype void do_firstcolumn (void);
  53. Prototype void do_firstnb (void);
  54. Prototype void do_lastcolumn (void);
  55. Prototype void do_goto (void);
  56. Prototype void do_screentop (void);
  57. Prototype void do_screenbottom (void);
  58. Prototype void do_findstr (void);
  59. Prototype void do_findr (void);
  60. Prototype void do_find (void);
  61. Prototype void search_operation (void);
  62. Prototype int case_strncmp (char *, char *, int);
  63.  
  64.  
  65. typedef struct Process PROC;
  66.  
  67. #define nomemory()  { memoryfail = 1; }
  68.  
  69. char RecallBuf[256];
  70.  
  71. void
  72. setpen(line)
  73. {
  74.     ED *ep = Ep;
  75.     RP *rp = ep->Win->RPort;
  76.  
  77.     short pen = (ep == BEp && line >= BSline && line <= BEline) ? ep->HGPen : ep->FGPen;
  78.     if (Comlinemode)
  79.     pen = ep->FGPen;
  80.     if (pen != rp->FgPen)
  81.     SetAPen(rp, pen);
  82. }
  83.  
  84. text_init(oldep, win, nw)
  85. ED *oldep;
  86. WIN *win;
  87. struct NewWindow *nw;
  88. {
  89.     ED *e;
  90.  
  91.     text_switch(NULL);
  92.     e = (ED *)allocb(sizeof(ED));
  93.     if (e == NULL)
  94.     return(0);
  95.     setmem(e, sizeof(ED), 0);
  96.     e->Win = win;
  97.     if (oldep) {
  98.     e->dirlock = (long)DupLock((BPTR)oldep->dirlock);
  99.  
  100.     movmem(&oldep->BeginConfig, &e->BeginConfig, (char *)&e->EndConfig - (char *)&e->BeginConfig);
  101.  
  102.     if (oldep->Font) {
  103.         e->Font = oldep->Font;
  104.         ++e->Font->tf_Accessors;
  105.         if (win)
  106.         SetFont(win->RPort, e->Font);
  107.     }
  108.     e->IWiny = oldep->IWiny + 16;
  109.     } else {
  110.     PROC *proc = (PROC *)FindTask(NULL);
  111.     e->dirlock = (long)DupLock((BPTR)proc->pr_CurrentDir);
  112.  
  113.     e->Insertmode = 1;
  114.     e->Tabstop = 4;
  115.     e->WWCol = -1;
  116.     e->Margin= 75;
  117.     e->FGPen = 1;
  118.     e->BGPen = 0;
  119.     e->HGPen = 2;
  120.     loadconfig(e);
  121.     }
  122.     e->Lines = 1;
  123.     e->Maxlines = 32;
  124.     e->List = (ubyte **)allocl(e->Maxlines);
  125.     e->List[0] = allocb(1);
  126.     e->List[0][0] = Current[0] = Clen = 0;
  127.     AddHead((LIST *)&DBase, (NODE *)e);
  128.     strcpy(e->Name, "unnamed");
  129.     Ep = e;
  130.  
  131.     if (nw) {
  132.     if (e->Winwidth && e->Winheight) {
  133.         nw->LeftEdge= e->Winx;
  134.         nw->TopEdge = e->Winy;
  135.         nw->Width    = e->Winwidth;
  136.         nw->Height    = e->Winheight;
  137.     } else {
  138.         nw->LeftEdge= 0;
  139.         nw->TopEdge = 0;
  140.         nw->Width    = 640;
  141.         nw->Height    = 200;
  142.     }
  143.     nw->DetailPen = e->BGPen;
  144.     nw->BlockPen  = e->FGPen;
  145.     }
  146.  
  147.     return(1);
  148. }
  149.  
  150. text_switch(win)
  151. WIN *win;
  152. {
  153.     ED *e;
  154.  
  155.     if (win)
  156.     text_sync();
  157.     if (win) {
  158.     for (e = (ED *)DBase.mlh_Head; e->Node.mln_Succ; e = (ED *)e->Node.mln_Succ) {
  159.         if (e->Win == win) {
  160.         Ep = e;
  161.         text_load();
  162.         if (!Ep->iconmode) {
  163.             set_window_params();
  164.             window_title();
  165.         }
  166.         return(1);
  167.         }
  168.     }
  169.     return(0);
  170.     }
  171. }
  172.  
  173.  
  174. text_sync()
  175. {
  176.     ED *ep = Ep;
  177.     char redraw = 0;
  178.     short len;
  179.     ubyte *ptr;
  180.  
  181.     for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
  182.     Current[len] = '\0';
  183.     Clen = len + 1;
  184.     if (!Comlinemode) {
  185.     if (strlen(ep->List[ep->Line]) != Clen) {
  186.         if (ptr = allocb(Clen+1)) {
  187.         ep->Modified = 1;
  188.         Overide = 0;
  189.         FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
  190.         ep->List[ep->Line] = ptr;
  191.         } else {
  192.         nomemory();
  193.         strcpy(Current, ep->List[ep->Line]);
  194.         Clen = strlen(Current);
  195.         }
  196.     } else {
  197.         if (strcmp(ep->List[ep->Line], Current)) {
  198.         ep->Modified = 1;
  199.         Overide = 0;
  200.         }
  201.     }
  202.     strcpy(ep->List[ep->Line], Current);
  203.     }
  204.     if (Nsu == 0) {
  205.     if (ep->Column - ep->Topcolumn >= Columns || ep->Column < ep->Topcolumn) {
  206.         redraw = 1;
  207.         ep->Topcolumn = ep->Column - (Columns>>1);
  208.         if (ep->Topcolumn < 0)
  209.         ep->Topcolumn = 0;
  210.     }
  211.     if (ep->Line - ep->Topline >= Rows || ep->Line < ep->Topline) {
  212.         redraw = 1;
  213.         ep->Topline = ep->Line - (Rows>>1);
  214.         if (ep->Topline < 0)
  215.         ep->Topline = 0;
  216.     }
  217.     }
  218.     while (ep->Column > Clen)
  219.     Current[Clen++] = ' ';
  220.     Current[Clen] = '\0';
  221.     if (redraw)
  222.     text_redisplay();
  223.     return((int)redraw);
  224. }
  225.  
  226. text_load()
  227. {
  228.     if (Comlinemode)
  229.     return(0);
  230.     strcpy(Current, Ep->List[Ep->Line]);
  231.     Clen = strlen(Current);
  232.     while (Ep->Column > Clen)
  233.     Current[Clen++] = ' ';
  234.     Current[Clen] = '\0';
  235. }
  236.  
  237. text_colno()
  238. {
  239.     return(Ep->Column);
  240. }
  241.  
  242. text_lineno()
  243. {
  244.     return(Ep->Line+1);
  245. }
  246.  
  247. text_lines()
  248. {
  249.     return(Ep->Lines);
  250. }
  251.  
  252. text_cols()
  253. {
  254.     return((int)Clen);
  255. }
  256.  
  257. text_imode()
  258. {
  259.     return((int)Ep->Insertmode);
  260. }
  261.  
  262. text_tabsize()
  263. {
  264.     return((int)Ep->Tabstop);
  265. }
  266.  
  267. ubyte *
  268. text_name()
  269. {
  270.     return(Ep->Name);
  271. }
  272.  
  273. void
  274. text_uninit()
  275. {
  276.     ED *ep = Ep;
  277.  
  278.     PMKill(ep);
  279.     freelist(ep->List, ep->Lines);
  280.     FreeMem(ep->List, ep->Maxlines * sizeof(char *));
  281.  
  282.     if (BEp == ep) {
  283.     BEp = NULL;
  284.     BSline = BEline = -1;
  285.     }
  286.     Remove((NODE *)ep);
  287.     if (ep->Font) {
  288.     SetFont(ep->Win->RPort, ep->Win->WScreen->RastPort.Font);
  289.     CloseFont(ep->Font);
  290.     }
  291.     UnLock((BPTR)ep->dirlock);
  292.     FreeMem(ep, sizeof(ED));
  293.     if (((ED *)DBase.mlh_Head)->Node.mln_Succ) {
  294.     Ep = (ED *)DBase.mlh_Head;
  295.     text_load();
  296.     } else {
  297.     Ep = NULL;
  298.     }
  299. }
  300.  
  301. void
  302. inversemode(n)
  303. {
  304.     RP *rp = Ep->Win->RPort;
  305.  
  306.     if (n) {
  307.     SetAPen(rp, ~Ep->BGPen);
  308.     SetDrMd(rp, JAM2|INVERSVID);
  309.     } else {
  310.     setpen(Ep->Line);
  311.     SetDrMd(rp, JAM2);
  312.     }
  313. }
  314.  
  315. void
  316. text_cursor(n)
  317. {
  318.     ED *ep = Ep;
  319.     RP *rp = ep->Win->RPort;
  320.  
  321.     movetocursor();
  322.     inversemode(n);
  323.     if (Current[ep->Column])
  324.     Text(rp, Current+ep->Column, 1);
  325.     else
  326.     Text(rp, " ", 1);
  327.     inversemode(0);
  328. }
  329.  
  330. void
  331. text_position(col, row)
  332. {
  333.     ED *ep = Ep;
  334.     text_sync();
  335.     if (col == 0)
  336.     col = -1;
  337.     ep->Column = ep->Topcolumn + col;
  338.     if (ep->Column > 254)
  339.     ep->Column = 254;
  340.     if (ep->Column < 0)
  341.     ep->Column = 0;
  342.     ep->Line = ep->Topline + row;
  343.     if (ep->Line >= ep->Lines)
  344.     ep->Line = ep->Lines - 1;
  345.     if (ep->Line < 0)
  346.     ep->Line = 0;
  347.     text_load();
  348.     text_sync();
  349. }
  350.  
  351. void
  352. displayblock(on)
  353. {
  354.     long start = Ep->Topline;
  355.     long lines = BEline - BSline + 1;
  356.  
  357.     if (start < BSline)
  358.     start = BSline;
  359.     if (!on) {
  360.     BSline = BEline = -1;
  361.     BEp = NULL;
  362.     }
  363.     if (Ep == BEp)
  364.     text_displayseg(start - Ep->Topline, lines);
  365. }
  366.  
  367. void
  368. text_redrawblock(ok)
  369. {
  370.     WIN *savewin = NULL;
  371.  
  372.     if (BEp) {
  373.     if (BEp != Ep) {
  374.         savewin = Ep->Win;
  375.         text_switch(BEp->Win);
  376.     }
  377.     if (BSline <= BEline && BSline >= 0 && BEline < Ep->Lines) {
  378.         if (!ok) {
  379.         BEp = NULL;
  380.         BSline = BEline = -1;
  381.         }
  382.         text_displayseg(0, Rows);
  383.     }
  384.     if (savewin)
  385.         text_switch(savewin);
  386.     }
  387.     if (!ok) {
  388.     BEp = NULL;
  389.     BSline = BEline = -1;
  390.     }
  391. }
  392.  
  393. void
  394. text_displayseg(start, n)
  395. {
  396.     short i, c;
  397.     ubyte *ptr;
  398.     ED *ep = Ep;
  399.     RP *rp = ep->Win->RPort;
  400.  
  401.     if (Nsu)
  402.     return;
  403.     for (i = start; i < start + n && i < Rows && ep->Topline + i < ep->Lines; ++i) {
  404.     if (Comlinemode) {
  405.         if (ep->Topline + i != ep->Line)
  406.         continue;
  407.         ptr = Current;
  408.         SetAPen(rp, ep->FGPen);
  409.     } else {
  410.         ptr = ep->List[ep->Topline + i];
  411.         setpen(i+ep->Topline);
  412.     }
  413.     for (c = ep->Topcolumn; c && *ptr; ++ptr, --c);
  414.     c = strlen(ptr);
  415.     if (c) {
  416.         Move(rp, COLT(0), ROWT(i));
  417.         Text(rp, ptr, (c > Columns) ? Columns : c);
  418.     }
  419.     }
  420. }
  421.  
  422. void
  423. text_redisplay()
  424. {
  425.     ED *ep = Ep;
  426.     RP *rp = ep->Win->RPort;
  427.  
  428.     if (Nsu)
  429.     return;
  430.     SetAPen(rp, ep->BGPen);
  431.     if (Comlinemode)
  432.     RectFill(rp, COL(0), ROW(Rows-1), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  433.     else
  434.     RectFill(rp, Xbase, Ybase, Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  435.     text_displayseg(0,Rows);
  436. }
  437.  
  438. void
  439. text_redisplaycurrline()
  440. {
  441.     ED *ep = Ep;
  442.     RP *rp = ep->Win->RPort;
  443.  
  444.     int row = ep->Line - ep->Topline;
  445.  
  446.     if (Nsu)
  447.     return;
  448.     SetAPen(rp, ep->BGPen);
  449.     RectFill(rp, COL(0), ROW(row), Xbase + Xpixs - 1, ROW(row+1)-1);
  450.     text_displayseg(row, 1);
  451. }
  452.  
  453. void
  454. text_write(str)
  455. ubyte *str;
  456. {
  457.     short len = strlen(str);
  458.     short i;
  459.     ED *ep = Ep;
  460.     RP *rp = ep->Win->RPort;
  461.  
  462.     if (Clen + len >= 255) {
  463.     text_sync();
  464.     text_load();
  465.     }
  466.     if (ep->Insertmode == 0) {
  467.     if (ep->Column + len >= 255)
  468.         goto fail;
  469.     movmem(str, Current + ep->Column, len);
  470.     if (ep->Column + len >= Clen)
  471.         Clen = ep->Column + len;
  472.     Current[Clen] = 0;
  473.     } else {
  474.     if (Clen + len >= 255)
  475.         goto fail;
  476.     movmem(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column);
  477.     movmem(str, Current + ep->Column, len);
  478.     Clen += len;
  479.     if (len < Columns - (ep->Column - ep->Topcolumn)) {
  480.         ScrollRaster(rp, -len * Xsize, 0 ,
  481.         COL(ep->Column - ep->Topcolumn),
  482.         ROW(ep->Line - ep->Topline),
  483.         COL(Columns) - 1,
  484.         ROW(ep->Line - ep->Topline + 1) - 1
  485.         );
  486.     }
  487.     }
  488.     i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len;
  489.     setpen(ep->Line);
  490.     Move(rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline));
  491.     Text(rp, str, i);
  492.     ep->Column += len;
  493.     if (ep->Column - ep->Topcolumn >= Columns)
  494.     text_sync();
  495. fail:
  496.     if (Comlinemode == 0 && ep->Wordwrap)
  497.     do_reformat(0);
  498. }
  499.  
  500. void
  501. do_up()
  502. {
  503.     ED *ep = Ep;
  504.     RP *rp = ep->Win->RPort;
  505.  
  506.     if (ep->Line) {
  507.     text_sync();
  508.     --ep->Line;
  509.     text_load();
  510.     if (Ep->Line < Ep->Topline) {
  511.         if (Nsu == 0) {
  512.         ScrollRaster(rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  513.         --ep->Topline;
  514.         text_displayseg(0, 1);
  515.         }
  516.     }
  517.     } else {
  518.     Abortcommand = 1;
  519.     }
  520. }
  521.  
  522. void
  523. do_scrolldown()
  524. {
  525.     ED *ep = Ep;
  526.     RP *rp = ep->Win->RPort;
  527.  
  528.     if (ep->Topline + Rows < ep->Lines) {
  529.     if (Nsu == 0) {
  530.         text_sync();
  531.         ScrollRaster(rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  532.         ++ep->Topline;
  533.         ++ep->Line;
  534.         text_load();
  535.         text_displayseg(Rows-1, 1);
  536.     }
  537.     } else {
  538.     Abortcommand = 1;
  539.     }
  540. }
  541.  
  542. void
  543. do_scrollup()
  544. {
  545.     ED *ep = Ep;
  546.     RP *rp = ep->Win->RPort;
  547.  
  548.     if (ep->Topline) {
  549.     if (Nsu == 0) {
  550.         text_sync();
  551.         ScrollRaster(rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  552.         --ep->Topline;
  553.         --ep->Line;
  554.         text_load();
  555.         text_displayseg(0, 1);
  556.     }
  557.     } else {
  558.     Abortcommand = 1;
  559.     }
  560. }
  561.  
  562. void
  563. do_down()
  564. {
  565.     ED *ep = Ep;
  566.     RP *rp = ep->Win->RPort;
  567.  
  568.     if (ep->Line + 1 < ep->Lines) {
  569.     text_sync();
  570.     ++ep->Line;
  571.     text_load();
  572.     if (ep->Line - ep->Topline >= Rows) {
  573.         if (Nsu == 0) {
  574.         ScrollRaster(rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  575.         ++ep->Topline;
  576.         text_displayseg(Rows-1, 1);
  577.         }
  578.     }
  579.     } else {
  580.     Abortcommand = 1;
  581.     }
  582. }
  583.  
  584. /*
  585.  *  PAGEUP
  586.  *  PAGEDOWN
  587.  *  PAGESET n    (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
  588.  *        can be > 100.
  589.  */
  590.  
  591. void
  592. do_page()
  593. {
  594.     int n, multiplier = 1;
  595.     ED *ep = Ep;
  596.     static short pctg = 80;
  597.  
  598.     switch(av[0][4]) {
  599.     case 'u':
  600.     multiplier = -1;
  601.     case 'd':
  602.     n = multiplier * Rows * pctg / 100;
  603.     if (!n)
  604.         n = multiplier;
  605.     if (n > 0 && ep->Topline >= ep->Lines - Rows)
  606.         return;
  607.     text_sync();
  608.     ep->Line += n;
  609.     ep->Topline += n;
  610.     if (ep->Line >= ep->Lines)
  611.         ep->Line = ep->Lines - 1;
  612.     if (ep->Line < 0)
  613.         ep->Line = 0;
  614.     if (ep->Topline >= ep->Lines)
  615.         ep->Topline = ep->Lines - Rows - 1;
  616.     if (ep->Topline < 0)
  617.         ep->Topline = 0;
  618.     text_load();
  619.     if (!text_sync())
  620.         text_redisplay();
  621.     break;
  622.     case 's':
  623.     pctg = atoi(av[1]);
  624.     break;
  625.     }
  626. }
  627.  
  628. void
  629. do_downadd()
  630. {
  631.     ED *ep = Ep;
  632.     ubyte *ptr;
  633.  
  634.     if (ep->Line + 1 == ep->Lines) {
  635.     ep->Modified = 1;
  636.     if (makeroom(32) && (ptr = allocb(1))) {
  637.         ep->List[ep->Lines] = ptr;
  638.         *ptr = 0;
  639.         ++ep->Lines;
  640.     } else {
  641.         nomemory();
  642.     }
  643.     }
  644.     do_down();
  645. }
  646.  
  647. void
  648. do_left()
  649. {
  650.     ED *ep = Ep;
  651.  
  652.     if (ep->Column) {
  653.     --ep->Column;
  654.     if (ep->Column < ep->Topcolumn)
  655.         text_sync();
  656.     } else {
  657.     Abortcommand = 1;
  658.     }
  659. }
  660.  
  661. void
  662. do_right()
  663. {
  664.     ED *ep = Ep;
  665.  
  666.     if (ep->Column != 254) {
  667.     if (Current[ep->Column] == 0) {
  668.         Current[ep->Column] = ' ';
  669.         Current[ep->Column+1]= '\0';
  670.         ++Clen;
  671.     }
  672.     ++ep->Column;
  673.     if (ep->Column - ep->Topcolumn >= Columns)
  674.         text_sync();
  675.     } else {
  676.     Abortcommand = 1;
  677.     }
  678. }
  679.  
  680. void
  681. do_tab()
  682. {
  683.     short n;
  684.     ED *ep = Ep;
  685.  
  686.     for (n = ep->Tabstop-(ep->Column % ep->Tabstop); n > 0; --n)
  687.     do_right();
  688. }
  689.  
  690. void
  691. do_backtab()
  692. {
  693.     short n;
  694.     ED *ep = Ep;
  695.  
  696.     n = ep->Column % ep->Tabstop;
  697.     if (!n)
  698.     n = ep->Tabstop;
  699.     for (; n > 0; --n)
  700.     do_left();
  701. }
  702.  
  703. void
  704. do_return()
  705. {
  706.     ubyte buf[256];
  707.     char *partial;
  708.  
  709.     if (Comlinemode) {
  710.     strcpy(buf, Current);
  711.     strcpy(RecallBuf, Current);
  712.     partial = Partial;
  713.     Partial = NULL;
  714.     escapecomlinemode();
  715.     if (partial) {
  716.         if (do_command(buf))
  717.         do_command(partial);
  718.         free(partial);
  719.     } else {
  720.         do_command(buf);
  721.     }
  722.     } else {
  723.     Ep->Column = 0;
  724.     text_sync();
  725.     do_downadd();
  726.     }
  727. }
  728.  
  729. void
  730. do_bs()
  731. {
  732.     ED *ep = Ep;
  733.     RP *rp = ep->Win->RPort;
  734.  
  735.     if (ep->Column) {
  736.     movmem(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1);
  737.     --ep->Column;
  738.     --Clen;
  739.     if (ep->Column < ep->Topcolumn) {
  740.         text_sync();
  741.     } else {
  742.         ScrollRaster(rp, Xsize, 0,
  743.         COL(ep->Column - ep->Topcolumn),
  744.         ROW(ep->Line   - ep->Topline),
  745.         COL(Columns)-1,
  746.         ROW(ep->Line - ep->Topline + 1)-1
  747.         );
  748.         if (Clen >= ep->Topcolumn + Columns) {
  749.         setpen(ep->Line);
  750.         Move(rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline));
  751.         Text(rp, Current + ep->Topcolumn + Columns - 1, 1);
  752.         }
  753.     }
  754.     if (Comlinemode == 0 && ep->Wordwrap)
  755.         do_reformat(0);
  756.     } else {
  757.     Abortcommand = 1;
  758.     }
  759. }
  760.  
  761.  
  762. /*
  763.  * esc, escimm
  764.  */
  765.  
  766. int Savetopline, Savecolumn, Savetopcolumn;
  767.  
  768. void
  769. do_recall()
  770. {
  771.     av[0] = (ubyte *)"escimm";
  772.     av[1] = (ubyte *)RecallBuf;
  773.     do_esc();
  774. }
  775.  
  776. void
  777. do_esc()
  778. {
  779.     ED *ep = Ep;
  780.     RP *rp = ep->Win->RPort;
  781.  
  782.     if (Comlinemode) {
  783.     escapecomlinemode();
  784.     return;
  785.     }
  786.     text_sync();
  787.     if (av[0][3] == 'i')
  788.     strcpy(Current, av[1]);
  789.     else
  790.     Current[0] = 0;
  791.     Clen = strlen(Current);
  792.     Comlinemode = 1;
  793.     returnoveride(1);
  794.     Savetopline = ep->Topline;
  795.     Savecolumn    = ep->Column;
  796.     Savetopcolumn = ep->Topcolumn;
  797.     ep->Column      = Clen;
  798.     ep->Topcolumn = 0;
  799.     ep->Topline   = ep->Line - Rows + 1;
  800.     SetAPen(rp, ep->BGPen);
  801.     RectFill(rp, COL(0), ROW(Rows-1), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  802.     SetAPen(rp, ep->FGPen);
  803.     Move(rp, COL(0), ROW(Rows-1) - 1);
  804.     Draw(rp, Xbase + Xpixs - 1, ROW(Rows - 1) - 1);
  805.     text_displayseg(Rows - 1, 1);
  806. }
  807.  
  808. void
  809. escapecomlinemode()
  810. {
  811.     ED *ep = Ep;
  812.     RP *rp = ep->Win->RPort;
  813.  
  814.     if (Partial) {
  815.     free(Partial);
  816.     Partial = NULL;
  817.     }
  818.     if (Comlinemode) {
  819.     strcpy(RecallBuf, Current);
  820.     Comlinemode = 0;
  821.     returnoveride(0);
  822.     ep->Topline = Savetopline;
  823.     ep->Column  = Savecolumn;
  824.     ep->Topcolumn = Savetopcolumn;
  825.     text_load();
  826.     SetAPen(rp, ep->BGPen);
  827.     RectFill(rp, COL(0), ROW(Rows-1)-1, Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  828.     SetAPen(rp, ep->FGPen);
  829.     text_displayseg(Rows - 2, 2);
  830.     }
  831. }
  832.  
  833. void
  834. do_del()
  835. {
  836.     ED *ep = Ep;
  837.     RP *rp = ep->Win->RPort;
  838.  
  839.     if (Current[ep->Column]) {
  840.     movmem(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column);
  841.     --Clen;
  842.     ScrollRaster(rp, Xsize, 0,
  843.         COL(ep->Column - ep->Topcolumn),
  844.         ROW(ep->Line - ep->Topline),
  845.         COL(Columns)-1,
  846.         ROW(ep->Line - ep->Topline + 1) - 1
  847.     );
  848.     if (Clen >= ep->Topcolumn + Columns) {
  849.         setpen(ep->Line);
  850.         Move(rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline));
  851.         Text(rp, Current+ep->Topcolumn+Columns-1, 1);
  852.     }
  853.     if (Comlinemode == 0 && ep->Wordwrap)
  854.         do_reformat(0);
  855.     }
  856. }
  857.  
  858. void
  859. do_top()
  860. {
  861.     text_sync();
  862.     Ep->Line = 0;
  863.     text_load();
  864.     text_sync();
  865. }
  866.  
  867. void
  868. do_bottom()
  869. {
  870.     text_sync();
  871.     Ep->Line = Ep->Lines - 1;
  872.     text_load();
  873.     text_sync();
  874. }
  875.  
  876. void
  877. do_firstcolumn()
  878. {
  879.     if (Ep->Column) {
  880.     Ep->Column = 0;
  881.     text_sync();
  882.     }
  883. }
  884.  
  885. void
  886. do_firstnb()
  887. {
  888.     for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column);
  889.     if (Current[Ep->Column] == 0)
  890.     Ep->Column = 0;
  891.     text_sync();
  892. }
  893.  
  894. void
  895. do_lastcolumn()
  896. {
  897.     short i;
  898.  
  899.     text_sync();
  900.     i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]);
  901.     if (i != Ep->Column) {
  902.     Ep->Column = i;
  903.     text_sync();
  904.     }
  905. }
  906.  
  907. /*
  908.  * GOTO [+/-]N
  909.  * GOTO BLOCK    start of block
  910.  * GOTO START    start of block
  911.  * GOTO END    end of block
  912.  */
  913.  
  914. void
  915. do_goto()
  916. {
  917.     short n, i;
  918.     ubyte *ptr = av[1];
  919.  
  920.     i = 0;
  921.     n = -1;
  922.  
  923.     switch(*ptr) {
  924.     case 'b':
  925.     case 's':
  926.     case 'B':
  927.     case 'S':
  928.     n = -1;
  929.     if (Ep == BEp)
  930.         n = BSline;
  931.     break;
  932.     case 'e':
  933.     case 'E':
  934.     n = -1;
  935.     if (Ep == BEp)
  936.         n = BEline;
  937.     break;
  938.     case '+':
  939.     i = 1;
  940.     case '-':
  941.     n = Ep->Line;
  942.     default:
  943.     n += atoi(ptr+i);
  944.     }
  945.     if (n >= Ep->Lines)
  946.     n = Ep->Lines - 1;
  947.     if (n < 0)
  948.     n = 0;
  949.     text_sync();
  950.     Ep->Line = n;
  951.     text_load();
  952.     text_sync();
  953. }
  954.  
  955. void
  956. do_screentop()
  957. {
  958.     text_sync();
  959.     Ep->Line = Ep->Topline;
  960.     text_load();
  961.     text_sync();
  962. }
  963.  
  964. void
  965. do_screenbottom()
  966. {
  967.     text_sync();
  968.     Ep->Line = Ep->Topline + Rows - 1;
  969.     if (Ep->Line < 0 || Ep->Line >= Ep->Lines)
  970.     Ep->Line = Ep->Lines - 1;
  971.     text_load();
  972.     text_sync();
  973. }
  974.  
  975. static ubyte Fstr[256];
  976. static ubyte Rstr[256];
  977. static short Srch_sign;
  978. static char Doreplace;
  979.  
  980. /*
  981.  * findstr, repstr
  982.  */
  983.  
  984. void
  985. do_findstr()
  986. {
  987.     if (av[0][0] == 'f')
  988.     strcpy(Fstr, av[1]);
  989.     else
  990.     strcpy(Rstr, av[1]);
  991. }
  992.  
  993. /*
  994.  * findr, nextr, prevr
  995.  */
  996.  
  997. void
  998. do_findr()
  999. {
  1000.     Doreplace = 1;
  1001.     Srch_sign = 1;
  1002.     switch(av[0][0]) {
  1003.     case 'f':
  1004.     strcpy(Fstr, av[1]);
  1005.     strcpy(Rstr, av[2]);
  1006.     break;
  1007.     case 'p':
  1008.     Srch_sign = -1;
  1009.     break;
  1010.     }
  1011.     search_operation();
  1012. }
  1013.  
  1014. /*
  1015.  * find, next, prev
  1016.  */
  1017.  
  1018. void
  1019. do_find()
  1020. {
  1021.     Doreplace = 0;
  1022.     Srch_sign = 1;
  1023.     switch(av[0][0]) {
  1024.     case 'f':
  1025.     strcpy(Fstr, av[1]);
  1026.     break;
  1027.     case 'p':
  1028.     Srch_sign = -1;
  1029.     break;
  1030.     }
  1031.     search_operation();
  1032. }
  1033.  
  1034.  
  1035. static char CaseIgnore;
  1036.  
  1037. void
  1038. search_operation()
  1039. {
  1040.     int flen = strlen(Fstr);
  1041.     int rlen = strlen(Rstr);
  1042.     char senabled = 0;
  1043.     ubyte *ptr;
  1044.     int i, col;
  1045.     ED *ep = Ep;
  1046.  
  1047.     CaseIgnore = ep->IgnoreCase;
  1048.     text_sync();
  1049.     if (!flen) {
  1050.     title("No find pattern");
  1051.     Abortcommand = 1;
  1052.     return;
  1053.     }
  1054.  
  1055.     col = ep->Column;
  1056.     if (col >= strlen(ep->List[ep->Line]))
  1057.     col = strlen(ep->List[ep->Line]);
  1058.     for (i = ep->Line;;) {
  1059.     ptr = ep->List[i];
  1060.     if (Srch_sign > 0) {
  1061.         while (ptr[col]) {
  1062.         if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1063.             goto found;
  1064.         senabled = 1;
  1065.         ++col;
  1066.         }
  1067.         senabled = 1;
  1068.         if (++i >= ep->Lines)
  1069.         break;
  1070.         col = 0;
  1071.     } else {
  1072.         while (col >= 0) {
  1073.         if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1074.             goto found;
  1075.         senabled = 1;
  1076.         --col;
  1077.         }
  1078.         senabled = 1;
  1079.         if (--i < 0)
  1080.         break;
  1081.         col = strlen(ep->List[i]);
  1082.     }
  1083.     }
  1084.     title("Pattern Not Found");
  1085.     Abortcommand = 1;
  1086.     return;
  1087.  
  1088. found:
  1089.     ep->Line = i;
  1090.     ep->Column = col;
  1091.  
  1092.     text_load();
  1093.     if (Doreplace) {
  1094.     if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
  1095.         title("Replace: Line Too Long");
  1096.         Abortcommand = 1;
  1097.         return;
  1098.     }
  1099.     if (Clen-col-flen >= 0) {
  1100.         movmem(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
  1101.         movmem(Rstr, Current+col, rlen);
  1102.         Clen += rlen-flen;
  1103.         ep->Column += rlen;
  1104.     }
  1105.     text_sync();
  1106.     text_redisplaycurrline();
  1107.     } else {
  1108.     text_sync();
  1109.     }
  1110. }
  1111.  
  1112. case_strncmp(s1, s2, len)
  1113. char *s1, *s2;
  1114. {
  1115.     if (CaseIgnore == 0)
  1116.     return(strncmp(s1, s2, len));
  1117.     for (; len; --len, ++s1, ++s2) {
  1118.     if ((*s1|0x20) != (*s2|0x20))
  1119.         return(1);
  1120.     if (((*s1 >= 'a' && *s1 <= 'z') || (*s1 >= 'A' && *s1 <= 'Z')) &&
  1121.         ((*s2 >= 'a' && *s2 <= 'z') || (*s2 >= 'A' && *s2 <= 'Z')))
  1122.     {
  1123.         continue;
  1124.     }
  1125.     if (*s1 != *s2)
  1126.         return(1);
  1127.     }
  1128.     return(0);
  1129. }
  1130.  
  1131.  
  1132.